# coding=utf-8
import datetime
import random

from django.db import transaction
from rest_framework.views import APIView
from rest_framework import generics
from utils import response_error, response_ok
from utils.exceptions import CustomError
from utils.permission import IsMemberUser
from apps.member.activity.models import MemberActivity
from .filters import MemberBargainRecordFilter, BargainActivityApplyFilter
from .models import Activity, BargainActivity, BargainActivityApply, MemberBargainRecord
from .serializers import BargainActivityApplySerializer, MemberBargainRecordListSerializer, \
    BargainActivityApplyDetailSerializer, BargainActivityApplyListSerializer


class BargainActivityApplyInfoView(generics.RetrieveAPIView):
    permission_classes = [IsMemberUser, ]
    queryset = BargainActivityApply.objects.filter()
    serializer_class = BargainActivityApplyDetailSerializer

    def retrieve(self, request, *args, **kwargs):
        # print(kwargs)  # {'activity_id': 2, 'pk': 12}
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return response_ok(serializer.data)


class BargainActivityView(APIView):
    '''帮砍'''
    permission_classes = [IsMemberUser, ]

    def post(self, request, activity_id):
        try:
            bargain_apply_id = request.data['bargain_apply_id']
            activity = Activity.get_instance_by_id(activity_id)
            activity_bargain = BargainActivity.objects.filter(activity=activity).first()
            member = request.user.member
            with transaction.atomic():
                bargain_apply = BargainActivityApply.objects.select_for_update().get(
                    id=bargain_apply_id)
                if bargain_apply.member_activity.status == MemberActivity.FINISH:
                    raise CustomError('已经砍价完成')

                # 判断是否已经砍过
                MemberBargainRecord.is_bargain(member, bargain_apply)
                bargain_arr = bargain_apply.bargain_arr.split(',')
                # bargain_arr = list(map(float, bargain_arr))
                # 砍掉金额
                bargain_amount = float(bargain_arr.pop())

                if bargain_apply.has_bargain_count - bargain_apply.bargain_count == 1:
                    # 最后一次砍价,  金额为 总金额减去已砍金额
                    bargain_amount = activity_bargain.old_price - activity_bargain.new_price - bargain_apply.has_bargain_amount
                    bargain_apply.has_bargain_amount = round(bargain_apply.has_bargain_amount + bargain_amount)
                    bargain_apply.remain_amount = round(bargain_apply.remain_amount - bargain_amount, 2)
                else:
                    bargain_apply.has_bargain_amount = round(bargain_apply.has_bargain_amount + bargain_amount)
                    bargain_apply.remain_amount = round(bargain_apply.remain_amount - bargain_amount, 2)
                # 更新
                bargain_apply.bargain_arr = ','.join(bargain_arr)
                bargain_apply.has_bargain_amount = round(bargain_apply.has_bargain_amount + bargain_amount)
                bargain_apply.remain_amount = round(bargain_apply.remain_amount - bargain_amount, 2)
                bargain_apply.has_bargain_count = bargain_apply.has_bargain_count + 1
                bargain_apply.save()

                if bargain_apply.has_bargain_count == bargain_apply.bargain_count or bargain_apply.remain_amount == 0:
                    # 完成砍价
                    member_activity = bargain_apply.member_activity
                    member_activity.status = MemberActivity.FINISH
                    member_activity.save()

                    # 优惠卷数量减一
                    activity_bargain.remain_count = activity_bargain.remain_count - 1
                    activity_bargain.save()

                # 记录砍价
                MemberBargainRecord.objects.create(bargain_activity=bargain_apply, member=member,
                                                   amount=bargain_amount)

                return response_ok({'bargain_amount': bargain_amount})
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))


class BargainActivityRecordListView(generics.ListAPIView):
    # permission_classes = [IsMemberUser, ]
    queryset = MemberBargainRecord.objects.filter()
    serializer_class = MemberBargainRecordListSerializer

    def filter_queryset(self, queryset):
        f = MemberBargainRecordFilter(self.request.GET, queryset)
        return f.qs


class BargainActivityApplyListView(generics.ListAPIView):
    # 报名列表
    queryset = BargainActivityApply.objects.filter()
    serializer_class = BargainActivityApplyListSerializer

    def filter_queryset(self, queryset):
        f = BargainActivityApplyFilter(self.request.GET, queryset=queryset)
        return f.qs


class BargainActivityApplyView(APIView):
    permission_classes = [IsMemberUser, ]

    def post(self, request, activity_id):
        try:
            activity = Activity.get_instance_by_id(activity_id)
            # name = request.data.get('name')
            # mobile = request.data.get('mobile')
            # if name and mobile:
            #     raise CustomError('姓名和手机号不能为空')
            member = request.user.member
            if activity.is_apply_activity(member):
                raise CustomError('已经报名给此活动。')

            bargain_activity = BargainActivity.objects.filter(activity=activity).first()
            bargain_apply = request.data
            # 砍价数量
            bargain_apply['bargain_count'] = random.randint(bargain_activity.min_bargain_count,
                                                            bargain_activity.max_bargain_count + 1)
            # 砍价还剩金额
            bargain_apply['remain_amount'] = bargain_activity.old_price - bargain_activity.new_price
            # 砍价金额数组
            # 第一次砍价金额
            first_amount = round(bargain_apply['remain_amount'] * random.uniform(0.2, 0.5), 2)
            bargain_arr_iter = BargainActivityApply.hb_generator(bargain_apply['bargain_count'] - 1,
                                                                 bargain_apply['remain_amount'] - first_amount)
            bargain_apply['bargain_arr'] = ','.join([str(num) for num in bargain_arr_iter]) + ',' + str(first_amount)
            # 砍价结束时间 当前时间+砍价有效期,  改为天数
            bargain_apply['end_time'] = datetime.timedelta(days=bargain_activity.valid_time) + datetime.datetime.now()
            with transaction.atomic():
                member_activity = MemberActivity.objects.create(member=member, activity=activity)
                # 定时结束结束砍价活动
                # end_task_time = datetime.datetime.utcfromtimestamp(end_time)
                # end_task_id = end_bargain_task.apply_async(args=[member_activity.id], eta=end_task_time).id
                # bargain_apply['end_task_id'] = end_task_id

                bargain_apply_ser = BargainActivityApplySerializer(data=bargain_apply)
                if bargain_apply_ser.is_valid(raise_exception=True):
                    bargain_apply = bargain_apply_ser.save(member_activity=member_activity)
                    return response_ok(bargain_apply.id)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()
